package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueService albumAttributeValueService;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private RabbitService rabbitService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        AlbumInfoServiceImpl proxyObject = (AlbumInfoServiceImpl) AopContext.currentProxy();

        //拿到登录的UserId
        Long userId = AuthContextHolder.getUserId();

        //保存专辑基本信息(album_info)
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setUserId(userId);
        // 默认审核通过（TODO 对接后续系统）
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        String payType = albumInfoVo.getPayType();
        //除了免费专辑 默认给五集免费
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)) {
            albumInfo.setTracksForFree(5);
        }

        int insert = albumInfoMapper.insert(albumInfo);
        log.info("保存专辑基本信息:{}", insert > 0 ? "成功" : "失败");

        //保存专辑的标签信息(album_attribute_value)
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        List<AlbumAttributeValue> attributeValues = albumAttributeValueVoList.stream().map(
                albumAttributeValueVo -> {
                    AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                    albumAttributeValue.setAlbumId(albumInfo.getId());
                    albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                    albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                    return albumAttributeValue;
                }
        ).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(attributeValues)) {
            boolean b = albumAttributeValueService.saveBatch(attributeValues);
            log.info("保存专辑标签信息：{}", b ? "sucess" : "fail");
        }

        proxyObject.saveAlbumStat(albumInfo.getId());

//        将专辑同步到ES中
        String isOpen = albumInfoVo.getIsOpen();
        if ("1".equals(isOpen)) {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId().toString());
            log.info("专辑微服务发送消息到专辑上架队列成功");
        }
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> pageParam, AlbumInfoQuery albumInfoQuery) {
        return albumInfoMapper.findUserAlbumPage(pageParam, albumInfoQuery);
    }

    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {


        // 基本信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (albumInfo == null) {
            throw new GuiguException(201, "该专辑不存在");
        }


        // 标签信息（属性id和属性值id）
        List<AlbumAttributeValue> attributeValues = albumAttributeValueMapper.selectList(
                new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId, albumId)
        );

        albumInfo.setAlbumAttributeValueVoList(attributeValues);

        return albumInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {

        // 1.修改专辑的基本信息
        // 1.1. 根据专辑id查询专辑的旧数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (albumInfo == null) {
            throw new GuiguException(201, "该专辑不存在");
        }

        BeanUtils.copyProperties(albumInfoVo, albumInfo); // 有的属性直接拷贝过期  vo没有的属性用老的AlbumInfo

        if (SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {

            albumInfo.setPrice(new BigDecimal("0.00"));
            albumInfo.setVipDiscount(new BigDecimal("-1.00"));
            albumInfo.setDiscount(new BigDecimal("-1.00"));
            albumInfo.setTracksForFree(0);
        } else {
            albumInfo.setTracksForFree(5);
        }
        int i = albumInfoMapper.updateById(albumInfo);
        log.info("修改专辑的基本信息{}", i > 0 ? "success" : "fail");

        // 2.专辑的标签信息
        // 2.1 删除该专辑的老标签信息
        LambdaQueryWrapper<AlbumAttributeValue> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AlbumAttributeValue::getAlbumId, albumId);
        int delete = albumAttributeValueMapper.delete(wrapper);
        log.info("删除专辑的旧标签数据：{}", delete > 0 ? "success" : "fail");

        // 2.2 查询该专辑的新标签信息
        List<AlbumAttributeValue> attributeValues = albumInfoVo.getAlbumAttributeValueVoList().stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());

            return albumAttributeValue;

        }).collect(Collectors.toList());


        if (!CollectionUtils.isEmpty(attributeValues)) {
            boolean b = albumAttributeValueService.saveBatch(attributeValues);
            log.info("保存专辑标签信息：{}", b ? "success" : "fail");
        }

        String isOpen = albumInfoVo.getIsOpen();

        if("1".equals(isOpen)){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId().toString());
            log.info("专辑微服务发送消息到专辑上架队列成功");
        }else{
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumInfo.getId().toString());
            log.info("专辑微服务发送消息到专辑下架队列成功");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeAlbumInfo(Long albumId) {

        // 1.删除专辑的基本信息
        // 查询专辑下是否有声音
        Long count = trackInfoMapper.selectCount(
                new LambdaQueryWrapper<TrackInfo>()
                        .eq(TrackInfo::getAlbumId, albumId)
        );
        if (count > 0) {
            throw new GuiguException(201, "该专辑下存在声音，请勿删除!");
        }
        int i = albumInfoMapper.deleteById(albumId);
        log.info("删除专辑的基本信息：{}", i > 0 ? "success" : "fail");

        // 2.删除专辑的标签信息
        int delete = albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId, albumId)
        );
        log.info("删除专辑的标签信息：{}", delete > 0 ? "success" : "fail");

        // 3.专辑的统计信息
        int delete1 = albumStatMapper.delete(
                new LambdaQueryWrapper<AlbumStat>()
                        .eq(AlbumStat::getAlbumId, albumId)
        );
        log.info("删除专辑的统计信息：{}", delete1 > 0 ? "success" : "fail");

        // 4.将专辑从es中删除
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());
        log.info("专辑微服务发送消息到专辑上架队列成功");

    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        return albumInfoMapper.selectList(
                new LambdaQueryWrapper<AlbumInfo>()
                        .eq(AlbumInfo::getUserId, userId)
        );
    }

    @Override
    public AlbumStatVo getAlbumStat(Long albumId) {

        return albumInfoMapper.getAlbumStat(albumId);
    }

    @Override
    public List<Long> getAlbumInfoIdList() {
        List<AlbumInfo> albumInfos = albumInfoMapper.selectList(null);
        return albumInfos.stream().map(AlbumInfo::getId).collect(Collectors.toList());
    }

    @Transactional
    public void saveAlbumStat(Long albumId) {
        ArrayList<String> albumStatus = new ArrayList<>();
        albumStatus.add(SystemConstant.ALBUM_STAT_PLAY);
        albumStatus.add(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        albumStatus.add(SystemConstant.ALBUM_STAT_BROWSE);
        albumStatus.add(SystemConstant.ALBUM_STAT_COMMENT);
        for (String status : albumStatus) {
            AlbumStat albumStat = new AlbumStat();
            albumStat.setAlbumId(albumId);
            albumStat.setStatType(status);
            albumStat.setStatNum(0);
            albumStatMapper.insert(albumStat);
        }
    }
}
